package com.sisgesbyte.services.proyeccion;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;

import com.sisgesbyte.common.ConstModAdministracion;
import com.sisgesbyte.common.ConstProyeccion;
import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.common.Validaciones;
import com.sisgesbyte.dao.administracion.MantCategoriaProductoDao;
import com.sisgesbyte.dao.administracion.MantenimientoMarcaDao;
import com.sisgesbyte.dao.beanDao.FiltrosBean;
import com.sisgesbyte.dao.beanDao.FiltrosSQLBean;
import com.sisgesbyte.dao.beanDao.ProyeccionCanalRequest;
import com.sisgesbyte.dao.proyeccion.MantProyeccionCategoriaClienteDao;
import com.sisgesbyte.data.entity.administracion.CategoriaProductoEntity;
import com.sisgesbyte.data.entity.administracion.MarcaEntity;
import com.sisgesbyte.data.entity.comun.GenericEntity;
import com.sisgesbyte.data.entity.comun.GenericResponseEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionCategoriaClienteEntity;
import com.sisgesbyte.services.commonBean.GenericGuardarResponse;
import com.sisgesbyte.services.commonBean.GenericResponse;
import com.sisgesbyte.services.proyeccion.bean.FiltroOpcionesCanalBean;
import com.sisgesbyte.services.proyeccion.bean.FiltroProyClienteBean;
import com.sisgesbyte.services.proyeccion.bean.ListaProyCanalCategoriaResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyCanalMarcasResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyCategoriaClienteResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionCatClienteDetalleResponse;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionClienteBean;
import com.sisgesbyte.services.proyeccion.bean.ListaProyeccionClienteResponse;
import com.sisgesbyte.services.proyeccion.bean.ProyGeneralCategoriaBean;
import com.sisgesbyte.services.proyeccion.bean.ProyeccionCatClienteDetalleBean;
import com.sisgesbyte.services.proyeccion.bean.ProyeccionCategoriaClienteBean;
import com.sisgesbyte.services.proyeccion.bean.ProyeccionGeneralMarcasBean;

@Stateless
public class MantProyeccionCanalServiceImpl implements
		MantProyeccionCanalService {

	@EJB
	private MantProyeccionCategoriaClienteDao mantProyeccionCategoriaClienteDao;
	@EJB
	private MantProyeccionCanalDetalleService mantProyeccionCanalDetalleService;
	@EJB
	private MantenimientoMarcaDao mantenimientoMarcaDao;
	@EJB
	private MantProyeccionClienteService mantProyeccionClienteService;
	@EJB
	private MantCategoriaProductoDao mantCategoriaProductoDao;
	private List<CategoriaProductoEntity> listaHijosCategoriaProd;
	private List<CategoriaProductoEntity> hijos;
	@Inject
	private Validaciones validaciones;
	
	@Override
	public ListaProyCategoriaClienteResponse listaCatClientes(
			String codTransaccion, FiltroOpcionesCanalBean filtroBean) {
		String mensajeTransaccionMetodo = "[listaCatClientes idTx=" + codTransaccion + "] - ";
		ListaProyCategoriaClienteResponse response = new ListaProyCategoriaClienteResponse();
		List<ProyeccionCategoriaClienteEntity> listaProyeccionCanales = null;
		try{
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();

			if(filtroBean.getZonaId() > 0){
				FiltrosBean listaZona = new FiltrosBean();
				List<String> campoZona = new ArrayList<String>();
				campoZona.add("pcc.zona_id");
				listaZona.setCampos(campoZona);
				listaZona.setOperador("=");
				filtro.add(listaZona);
				valores.add(filtroBean.getZonaId());
			}
			
			if(filtroBean.getPeriodoId() > 0){
				FiltrosBean listaPeriodo = new FiltrosBean();
				List<String> campoPeriodo = new ArrayList<String>();
				campoPeriodo.add("pcc.periodo_id");
				listaPeriodo.setCampos(campoPeriodo);
				listaPeriodo.setOperador("=");
				filtro.add(listaPeriodo);
				valores.add(filtroBean.getPeriodoId());
			}
			
			if(filtroBean.getCanalId() > 0){
				FiltrosBean listaCanal = new FiltrosBean();
				List<String> campoCanal = new ArrayList<String>();
				campoCanal.add("pcc.categoria_cliente_id");
				listaCanal.setCampos(campoCanal);
				listaCanal.setOperador("=");
				filtro.add(listaCanal);
				valores.add(filtroBean.getCanalId());
			}
			
			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			
			listaProyeccionCanales = mantProyeccionCategoriaClienteDao.listaProyeccionCategoriaCliente(filtroSQL);
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		if(listaProyeccionCanales.size() > 0){
			List<ProyeccionCategoriaClienteBean> listaCanales = new ArrayList<ProyeccionCategoriaClienteBean>();
			BigDecimal montoTotal = BigDecimal.ZERO;
			for(ProyeccionCategoriaClienteEntity ls : listaProyeccionCanales){
				ProyeccionCategoriaClienteBean bean = new ProyeccionCategoriaClienteBean();
				bean.setBandaPeriodo(validaciones.validarCamposString(ls.getBanda_periodo()));
				bean.setCategoriaCliente(validaciones.validarCamposString(ls.getCategoria_cliente()));
				bean.setCategoriaClienteId(ls.getCategoria_cliente_id());
				bean.setId(ls.getId());
				bean.setMontoProyectado(ls.getMonto_proyectado());
				bean.setPeriodoId(ls.getPeriodo_id());
				bean.setZonaId(ls.getZona_id());
				montoTotal =montoTotal.add(ls.getMonto_proyectado());
				
				BigDecimal montoTotalAsignado = BigDecimal.ZERO;
				//obtenemos la asignacion proyectada para validar si se asigno toda la proyeccion dada
				try{
					FiltroProyClienteBean filtroCliente = new FiltroProyClienteBean();
					filtroCliente.setIdPeriodo(ls.getPeriodo_id());
					filtroCliente.setIdZona(ls.getZona_id());
					filtroCliente.setIdCanal(ls.getCategoria_cliente_id());
					ListaProyeccionClienteResponse serviceCliente = mantProyeccionClienteService.mostrarProyeccionCLiente(codTransaccion, filtroCliente);
					if(serviceCliente.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
						for(ListaProyeccionClienteBean listaCli : serviceCliente.getListaProyeccionCliente()){
							montoTotalAsignado = montoTotalAsignado.add(listaCli.getMontoProyectada());
						}
					}
					
				}catch(Exception e){
					montoTotalAsignado = BigDecimal.ZERO;
				}
				bean.setMontoProyectadoAsignado(montoTotalAsignado);
				
				int val = ls.getMonto_proyectado().compareTo(montoTotalAsignado);
			    if( val == 0 ){
			    	bean.setColorMontoProyectado(ConstProyeccion.COLOR_VERDE);
			    }else if( val == 1 ){
			    	bean.setColorMontoProyectado(ConstProyeccion.COLOR_ROJO);
			    }
			    else if( val == -1 ){
			    	bean.setColorMontoProyectado(ConstProyeccion.COLOR_AMARILLO);
			    };
				
				listaCanales.add(bean);
			}
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaProyeccionCategoriaCliente(listaCanales);
			response.setMontoTotalProyectado(montoTotal);
		
		} else {
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
		}

		return response;
	}

	@Override
	public GenericGuardarResponse nuevaProyeccionCategoriaCliente(
			String codTransaccion, ProyeccionCategoriaClienteBean request) {
		String mensajeTransaccionMetodo = "[nuevaProyeccionCategoriaCliente idTx=" + codTransaccion + "] - ";
		GenericGuardarResponse response = new GenericGuardarResponse();
		
		try{
			ProyeccionCanalRequest req = new ProyeccionCanalRequest();
			
			req.setCanalId(request.getCategoriaClienteId());
			req.setCodigo_banda(validaciones.validarCamposString(request.getBandaPeriodo()));
			req.setMonto_proyectado(request.getMontoProyectado());
			req.setPeriodoId(request.getPeriodoId());
			req.setZonaId(request.getZonaId());
			
			GenericResponseEntity nuevaProy = mantProyeccionCategoriaClienteDao.guardarProyeccionCategoriaCliente(req);
			
			if(nuevaProy.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				response.setIdTransaccion(codTransaccion);
				response.setCodigoSaved(validaciones.validarCamposString(nuevaProy.getCodigo()));
				response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
				response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			}else{
				response.setCodigoRespuesta(String.valueOf(nuevaProy.getCod_error()));
				response.setMensajeRespuesta(nuevaProy.getMsj_error());
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
		}
		
		return response;
	}

	@Override
	public GenericResponse editarProyeccionCategoriaCliente(
			String codTransaccion, ProyeccionCategoriaClienteBean request) {
		String mensajeTransaccionMetodo = "[editarProyeccionCategoriaCliente idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		try{
			ProyeccionCanalRequest req = new ProyeccionCanalRequest();
			req.setId(request.getId());
			req.setCanalId(request.getCategoriaClienteId());
			req.setCodigo_banda(validaciones.validarCamposString(request.getBandaPeriodo()));
			req.setMonto_proyectado(request.getMontoProyectado());
			req.setPeriodoId(request.getPeriodoId());
			req.setZonaId(request.getZonaId());
			GenericEntity editProy = mantProyeccionCategoriaClienteDao.actualizarProyeccionCategoriaCliente(req);
			
			if(editProy.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				response.setIdTransaccion(codTransaccion);
				response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
				response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			}else{
				response.setCodigoRespuesta(String.valueOf(editProy.getCod_error()));
				response.setMensajeRespuesta(editProy.getMsj_error());
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
		}
		
		return response;
	}

	@Override
	public GenericResponse deleteProyeccionCategoriaCliente(
			String codTransaccion, int codProyeccion) {
		String mensajeTransaccionMetodo = "[deleteProyeccionCategoriaCliente idTx=" + codTransaccion + "] - ";
		GenericResponse response = new GenericResponse();
		
		try{
			GenericEntity deleteProy = mantProyeccionCategoriaClienteDao.eliminarProyeccionCategoriaCliente(codProyeccion);
			
			if(deleteProy.getCod_error() == Integer.valueOf(ConstantesInternasSistema.CODIGO_EXITO)){
				response.setIdTransaccion(codTransaccion);
				response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
				response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			}else{
				response.setCodigoRespuesta(String.valueOf(deleteProy.getCod_error()));
				response.setMensajeRespuesta(deleteProy.getMsj_error());
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al registrar la Proyeccion en BD " + e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_NUEVO_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_NUEVO_MSJ_IDT);
		}
		
		return response;
	}

	@Override
	public ListaProyCanalMarcasResponse mostrarProyCanalMarcas(
			String codTransaccion, FiltroOpcionesCanalBean filtrosSQL) {
		String mensajeTransaccionMetodo = "[mostrarProyZonaMarcas idTx=" + codTransaccion + "] - ";
		ListaProyCanalMarcasResponse response = new ListaProyCanalMarcasResponse();
		
		List<MarcaEntity> listaMarcas = null;
		try{
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			List<Object> valores = new ArrayList<>();
			List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();
			FiltrosBean listaPeriodo = new FiltrosBean();
			List<String> campoPeriodo = new ArrayList<String>();
			campoPeriodo.add("active");
			listaPeriodo.setCampos(campoPeriodo);
			listaPeriodo.setOperador("=");
			filtro.add(listaPeriodo);
			valores.add(true);
			filtroSQL.setListaFiltros(filtro);
			filtroSQL.setListaValores(valores);
			//1.- Obtenemos la lista de marcas de productos
			listaMarcas =mantenimientoMarcaDao.listaMarcas(filtroSQL);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar marcas de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		ListaProyeccionCatClienteDetalleResponse detalle = null;
		try{
			FiltroOpcionesCanalBean filtroBean = new FiltroOpcionesCanalBean();
			filtroBean.setPeriodoId(filtrosSQL.getPeriodoId());
			filtroBean.setCanalId(filtrosSQL.getCanalId());
			filtroBean.setZonaId(filtrosSQL.getZonaId());
			filtroBean.setTxtBuscar("");
			//2.-capturamos el detalle de proyeccion del canal
			detalle =mantProyeccionCanalDetalleService.listaProyeccionCatClienteDetalle(codTransaccion, filtroBean);
			if(!detalle.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
				response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
				response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
				return response;
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar el detalle de proyeccion de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		List<ProyeccionGeneralMarcasBean> listaProyeccionCanalMarcas = new ArrayList<ProyeccionGeneralMarcasBean>();
		for(MarcaEntity marca : listaMarcas){
			ProyeccionGeneralMarcasBean bean = new ProyeccionGeneralMarcasBean();
			bean.setIdMarca(marca.getId());
			bean.setMarca(validaciones.validarCamposString(marca.getMarca()));
			BigDecimal totalMarca = BigDecimal.ZERO;
				try{
					for(ProyeccionCatClienteDetalleBean ls : detalle.getListaProyClienteDetalle()){
						if(marca.getId()==ls.getMarcaId()){
							totalMarca = totalMarca.add(ls.getCantidadProyectada().multiply(ls.getPrecioPromedio()));
						}
					}
				}catch(Exception e){
					System.out.println("Error al obtener monto " + e);
				}
			bean.setMontoTotal(totalMarca);
			if(totalMarca.compareTo(BigDecimal.ZERO) > 0){
				listaProyeccionCanalMarcas.add(bean);
			}
		}
		
		if (listaProyeccionCanalMarcas.size() > 0) {
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaProyeccionCanalMarcas(listaProyeccionCanalMarcas);;
		} else {
			System.out.println("No se encontro Datos");
			response.setCodigoRespuesta(ConstModAdministracion.MANT_ELIMINAR_COD_IDF);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_ELIMINAR_MSJ_IDF.replace("msj", mensajeTransaccionMetodo));
		}
		
		return response;
	}

	@Override
	public ListaProyCanalCategoriaResponse mostrarProyCanalCategoria(
			String codTransaccion, FiltroOpcionesCanalBean filtrosSQL) {
		String mensajeTransaccionMetodo = "[mostrarProyZonaMarcas idTx=" + codTransaccion + "] - ";
		ListaProyCanalCategoriaResponse response = new ListaProyCanalCategoriaResponse();
		
		
		List<CategoriaProductoEntity> listaCategoriaProd = null;
		try{
			
			//1.- obtenemos la lista de categoria de productos
			listaCategoriaProd = mantCategoriaProductoDao.listarCategoriasProd(null);
			this.listaHijosCategoriaProd = listaCategoriaProd;
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar las proyecciones de categorias productos de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		ListaProyeccionCatClienteDetalleResponse detalle = null;
		try{
			FiltroOpcionesCanalBean filtroBean = new FiltroOpcionesCanalBean();
			filtroBean.setPeriodoId(filtrosSQL.getPeriodoId());
			filtroBean.setCanalId(filtrosSQL.getCanalId());
			filtroBean.setZonaId(filtrosSQL.getZonaId());
			filtroBean.setTxtBuscar("");
			//2.-capturamos el detalle de proyeccion del canal
			detalle =mantProyeccionCanalDetalleService.listaProyeccionCatClienteDetalle(codTransaccion, filtroBean);
			if(!detalle.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
				response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
				response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
				return response;
			}
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo+ "Hubo un error al listar el detalle de proyeccion de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		List<ProyGeneralCategoriaBean> listaCategoriaProy = new ArrayList<ProyGeneralCategoriaBean>();
		for(CategoriaProductoEntity categoria : listaCategoriaProd){
			ProyGeneralCategoriaBean bean = new ProyGeneralCategoriaBean();
			bean.setId(categoria.getId());
			bean.setCategoria(categoria.getNombre());
			bean.setIdPadre(categoria.getPadre_id());
			
			hijos = new ArrayList<CategoriaProductoEntity>();
			//agregamos al padre
			hijos.add(categoria);
			//buscamos sus hijos
			capturarHijos(categoria.getId());
			//buscamos los montos de todos sus hijos
			BigDecimal total = BigDecimal.ZERO;
			try{
				for(CategoriaProductoEntity h :hijos){
					for(ProyeccionCatClienteDetalleBean proy : detalle.getListaProyClienteDetalle()){
						if(h.getId() == proy.getCategoriaProductoId()){
							total =total.add(proy.getPrecioPromedio().multiply(proy.getCantidadProyectada()));
						}
					}
				}
			}catch(Exception e){
				total = BigDecimal.ZERO;
			}
			
			bean.setMontoTotal(total);
			
			if(total.compareTo(BigDecimal.ZERO) > 0){
				listaCategoriaProy.add(bean);
			}
		}

		if (listaCategoriaProy.size() > 0) {
			response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
			response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
			response.setListaProyCanalCategoria(listaCategoriaProy);
		} else {
			response.setCodigoRespuesta(ConstModAdministracion.MANT_ELIMINAR_COD_IDF);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_ELIMINAR_MSJ_IDF.replace("msj", mensajeTransaccionMetodo));
		}
		return response;
		
	}
	public void capturarHijos(int idPadre){
		for(CategoriaProductoEntity hijo :listaHijosCategoriaProd){
			if(idPadre == hijo.getPadre_id()){
				hijos.add(hijo);
				capturarHijos(hijo.getId());
			}
		}
	}
}
